package com.googlecode.linkmein.domain;

import org.apache.commons.lang.StringUtils;
import ymsg.network.YahooGroup;
import ymsg.network.YahooUser;

import java.io.IOException;
import java.util.ArrayList;

public class YIM implements InstantMessenger {
    private String userName;
    private String password;

    public YIM() {

    }

    protected YIM(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }

    public String getUserName() {
        return userName;
    }

    public static YIM get(String userName, String password) {
        return new YIM(userName, password);
    }

    public Result login() {
        ymsg.network.Session ysm = null;
        Result result = null;
        try {
            ysm = new ymsg.network.Session();
            ysm.login(userName, password);
            result = new Result(ResultType.SUCCESSFUL, "Login successfully.");
        } catch (Exception e) {
            result = new Result(ResultType.FAILED, "Failed to Login.");
        } finally {
            try {
                ysm.logout();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public Employee find(Employees employees) {
        for (Employee employee : employees) {
            if (StringUtils.equalsIgnoreCase(employee.getYIM(), this.getUserName())) {
                return employee;
            }
        }
        return Employee.NULL;
    }

    public void initialize(Employee employee) {
        if (StringUtils.isEmpty(employee.getYIM())) {
            employee.setYim(this.userName);
        }
    }

    private Result inviteFriend(String yahooId, String groupName) {
        ymsg.network.Session ysm = null;
        Result result = null;
        try {
            ysm = new ymsg.network.Session();
            ysm.login(userName, password);
            ysm.addFriend(yahooId, groupName);
            result = new Result(ResultType.SUCCESSFUL, "Added successfully.");
        } catch (Exception e) {
            result = new Result(ResultType.FAILED, "Failed to add.");
        } finally {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                ysm.logout();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public Result inviteFriend(Employee employee) {
        return inviteFriend(employee.getYIM(), employee.getProject().getName());
    }

    public ArrayList<String> getFriends() {
        ymsg.network.Session ysm = null;
        ArrayList<String> friends = new ArrayList<String>();
        try {
            ysm = new ymsg.network.Session();
            ysm.login(userName, password);
            for (YahooGroup group : ysm.getGroups()) {
                for (Object member : group.getMembers()) {
                    friends.add(((YahooUser) member).getId());
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                ysm.logout();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return friends;
    }

    public Results inviteAndRegroupFriends(Employees employees) {
        ymsg.network.Session session = null;
        Results results = new Results();
        try {
            session = new ymsg.network.Session();
            session.login(userName, password);
            for (Employee employee : employees) {
                results.add(inviteAndRegroup(session, employee));
            }
        } catch (Exception e) {
            results.add(new Result(ResultType.FAILED, e.getMessage()));
        }
        finally {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                session.logout();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return results;
    }

    private Result inviteAndRegroup(ymsg.network.Session session, Employee employee) throws InterruptedException {
        if (employee.isFriend(session)) {
            try {
                String oldGroupName = queryGroup(session, employee);
                String newGroupName = employee.getProject().getName();
                if (!oldGroupName.equals(newGroupName)) {
                    session.addFriend(employee.getYIM(), newGroupName);
                    Thread.sleep(1000);//yahoo api is weird sometimes, the delay will make the adding and removing more credible
                    session.removeFriend(employee.getYIM(), oldGroupName);
                    Thread.sleep(1000);
                    return new Result(ResultType.ALREADY_HAD, "alreay had [" + employee.getYIM() + "], now moved to a new group [" + newGroupName + "]");
                }
                return new Result(ResultType.ALREADY_HAD, "alreay had [" + employee.getYIM() + "]");
            } catch (IOException e) {
                return new Result(ResultType.FAILED, e.getMessage());
            }
        } else {
            try {
                session.addFriend(employee.getYIM(), employee.getProject().getName());
                Thread.sleep(1000);
                return new Result(ResultType.SUCCESSFUL, "successfully sending add request to [" + employee.getYIM() + "]");
            } catch (Exception e) {
                return new Result(ResultType.FAILED, e.getMessage());
            }
        }
    }

    private String queryGroup(ymsg.network.Session session, Employee employee) {
        for (YahooGroup group : session.getGroups()) {
            for (Object memmber : group.getMembers()) {
                if (((YahooUser) memmber).getId().equals(employee.getYIM())) {
                    return group.getName();
                }
            }
        }
        return null;
    }
}
